﻿/**************************************************************
 *
 * 命名空间：Sgr.DataCategories.Application.Queries.Impl
 * 创建时间：2025/3/19
 * 描述：行政区划查询服务实现
 *
 **************************************************************/

using MediatR;
using Microsoft.EntityFrameworkCore;
using Sgr.Application.Queries;
using Sgr.Application.ViewModels;
using Sgr.DataCategories.Application.Queries;
using Sgr.DataCategories.Application.ViewModels;
using Sgr.DataCategories.Domain.AdministrativeDivisions;
using Sgr.DataCategories.Services;
using Sgr.DataCategories.Stores;
using Sgr.Domain.Entities;
using Sgr.Exceptions;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Sgr.DataCategories.Application.Queries.Impl
{
    /// <summary>
    /// 行政区划查询服务实现
    /// </summary>
    public class AdministrativeDivisionQueries : IAdministrativeDivisionQueries
    {
        private readonly ISgrQueryContext _context;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="context">读库上下文</param>
        public AdministrativeDivisionQueries(ISgrQueryContext context)
        {
            _context = context;
        }

        /// <summary>
        /// 根据ID获取行政区划
        /// </summary>
        /// <param name="id">行政区划ID</param>
        /// <param name="cancellationToken"></param>
        /// <returns>行政区划视图模型</returns>
        /// <exception cref="BusinessException">当ID无效时抛出</exception>
        public async Task<OutAdministrativeDivisionViewModel?> GetByIdAsync(long id, CancellationToken cancellationToken = default)
        {
            if (id <= 0)
                throw new BusinessException($"Id({id})需大于零");

            var query = _context.Query<AdministrativeDivision>()
                .Where(f => f.Id == id)
                .Select(f => new OutAdministrativeDivisionViewModel
                {
                    Id = f.Id,
                    Code = f.Code,
                    Name = f.Name,
                    ShortName = f.ShortName,
                    Description = f.Description,
                    State = f.State,
                    OrderNumber = f.OrderNumber,
                    ParentId = f.ParentId
                });

            return await _context.FirstOrDefaultAsync(query, cancellationToken);
        }

        /// <summary>
        /// 获取行政区划列表
        /// </summary>
        /// <param name="request">查询条件模型</param>
        /// <param name="cancellationToken"></param>
        /// <returns>分页结果</returns>
        /// <exception cref="ArgumentNullException">当请求为空时抛出</exception>
        public async Task<PagedResponse<OutAdministrativeDivisionViewModel>> GetPagedListAsync(InAdministrativeDivisionSearchModel request, CancellationToken cancellationToken = default)
        {
            Check.NotNull(request, nameof(request));

            // 构建基础查询
            var query = _context.Query<AdministrativeDivision>();

            // 应用筛选条件
            // 按代码筛选
            if (!string.IsNullOrWhiteSpace(request.Code))
                query = query.Where(f => f.Code == request.Code);

            // 按级别筛选
            if (request.Level.HasValue)
                query = query.Where(f => f.Level == request.Level.Value);

            // 按父级ID筛选
            if (request.ParentId.HasValue)
                query = query.Where(f => f.ParentId == request.ParentId.Value);

            // 按状态筛选
            if (request.States.HasValue)
                query = query.Where(f => f.State == request.States.Value);

            // 按名称筛选
            if (!string.IsNullOrWhiteSpace(request.Name))
            {
                query = query.Where(f => f.Name.Contains(request.Name)
                || (f.ShortName != null && f.ShortName.Contains(request.Name))
                || (f.PinyinName != null && f.PinyinName.Contains(request.Name))
                || (f.PinyinAbbr != null && f.PinyinAbbr.Contains(request.Name)));
            }

            // 排序
            //query = query.OrderBy(f => f.OrderNumber).ThenBy(f => f.Code);
            query = query.OrderBy(f => f.OrderNumber).ThenByDescending(f => f.Id);

            // 转换为ViewModel
            var pagedQuery = query.Select(f => new OutAdministrativeDivisionViewModel
            {
                Id = f.Id,
                Code = f.Code,
                Name = f.Name,
                ShortName = f.ShortName,
                Description = f.Description,
                State = f.State,
                OrderNumber = f.OrderNumber,
                ParentId = f.ParentId
            });

            // 执行分页查询
            return await _context.PagedListByPageSizeAsync(
                pagedQuery,
                request.PageIndex,
                request.PageSize,
                cancellationToken);
        }

        /// <summary>
        /// 获取指定父级下的行政区划列表
        /// </summary>
        /// <param name="parentId">父级行政区划ID</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>行政区划视图模型集合</returns>
        public async Task<IEnumerable<OutAdministrativeDivisionViewModel>> GetListAsync(
            long parentId,
            CancellationToken cancellationToken = default)
        {
            // 构建基础查询
            var query = _context.Query<AdministrativeDivision>();

            // 应用筛选条件
            query = query.Where(f => f.ParentId == parentId);

            // 排序
            query = query.OrderBy(f => f.OrderNumber).ThenByDescending(f => f.Id);

            // 转换为ViewModel
            var pagedQuery = query.Select(f => new OutAdministrativeDivisionViewModel
            {
                Id = f.Id,
                Code = f.Code,
                Name = f.Name,
                ShortName = f.ShortName,
                Description = f.Description,
                State = f.State,
                OrderNumber = f.OrderNumber,
                ParentId = f.ParentId
            });

            // 执行分页查询
            return await _context.ToListAsync(pagedQuery, cancellationToken);
        }

        /// <summary>
        /// 获取所有行政区划列表
        /// </summary>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns></returns>
        public async Task<IEnumerable<OutAdministrativeDivisionViewModel>> GetNormalListAsync(CancellationToken cancellationToken = default)
        {
            // 构建基础查询
            var query = _context.Query<AdministrativeDivision>().Where(f => f.State == EntityStates.Normal);

            // 排序
            query = query.OrderBy(f => f.OrderNumber).ThenByDescending(f => f.Id);

            // 转换为ViewModel
            var pagedQuery = query.Select(f => new OutAdministrativeDivisionViewModel
            {
                Id = f.Id,
                Code = f.Code,
                Name = f.Name,
                ShortName = f.ShortName,
                Description = f.Description,
                State = f.State,
                OrderNumber = f.OrderNumber,
                ParentId = f.ParentId
            });

            // 执行分页查询
            return await _context.ToListAsync(pagedQuery, cancellationToken);
        }

        /// <summary>
        /// 获取所有行政区划条目列表
        /// </summary>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>行政区划名称和值的列表</returns>
        public async Task<IList<NameValue>> GetItemsAsync(CancellationToken cancellationToken = default)
        {
            // 构造行政区划查询请求
            var request = new InAdministrativeDivisionSearchModel
            {
                PageSize = int.MaxValue, // 获取所有行政区划
                States = EntityStates.Normal // 只查询启用状态的记录
            };

            // 查询行政区划数据
            var response = await GetPagedListAsync(request, cancellationToken);

            // 按排序号排序所有项目
            var sortedItems = response.Items.ToList();

            // 使用递归方法构建层级关系
            IList<NameValue> result = new List<NameValue>();
            //BuildAdministrativeDivisionHierarchy(sortedItems, result, null);
            BuildAdministrativeDivisionHierarchy(sortedItems, result, 0);

            return result;
        }

        /// <summary>
        /// 递归构建行政区划层级字典项
        /// </summary>
        /// <param name="allItems">所有行政区划项</param>
        /// <param name="result">构建结果集合</param>
        /// <param name="parentId">父级ID</param>
        private static void BuildAdministrativeDivisionHierarchy(
            IEnumerable<OutAdministrativeDivisionViewModel> allItems,
            IList<NameValue> result,
            long? parentId)
        {
            // 查找指定父ID下的所有行政区划
            var childrenItems = allItems.Where(item => item.ParentId == parentId);

            foreach (var item in childrenItems)
            {
                // 将当前行政区划添加到结果集合
                // NameValue构造函数：name(名称), value(代码), parentValue(父级代码)
                result.Add(new NameValue(item.Name, item.Id.ToString(), (parentId ?? 0).ToString()));

                // 递归处理子级行政区划，将当前项的ID和代码作为子级的父级ID和父级代码
                BuildAdministrativeDivisionHierarchy(allItems, result, item.Id);
            }
        }
    }
}